package com.zyht.bank.intercepter;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.wx.core.process.WxApi;
import com.wx.core.vo.response.Fans;
import com.wx.entity.SysWxuser;
import com.wx.entity.WxFansUser;
import com.wx.entity.WxFansUserExample;
import com.wx.model.dictionary.Constant;
import com.wx.service.SysWxTokenService;
import com.wx.service.WxFansUserService;
import com.zyht.common.util.HttpUtils;
import com.zyht.common.util.SpecialCharacterFilterUtil;
import com.zyht.wechat.WechatOperations;
import com.zyht.wechat.framework.OAuth2AndBind;
import com.zyht.wechat.framework.env.WechatEnv;

/**
 * <b>描述：</b>微信统一鉴权,经过此拦截器的controller可以直接从request对象中获取openid和state<br/>
 * <b>作者：</b>Bob <br/>
 * <b>修改日期：</b>2017年1月15日 - 下午1:34:29<br/>
 */
public class WechatAuthInterceptor implements HandlerInterceptor {

	private Logger logger = LoggerFactory.getLogger(getClass());

	// 拦截请求列表
	private List<String> handleUrlList;

	// 拦截指定前缀下的请求
	private String handlePrefix = "/oauth2";
	
	@Resource
	private SysWxTokenService sysWxTokenService;
	
	@Resource
	private WxFansUserService wxFansUserService;

	@Override
	public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler)
		throws Exception{
		
		String servletPath = request.getServletPath();
		if(isNeedHandle(servletPath, handler)){
			HttpSession session = request.getSession();
			WxFansUser fan = (WxFansUser) session.getAttribute(Constant.CURRENT_USER_FANINFO_FROM_EVENT_VIEW);
			/*ExamBindings bind = (ExamBindings) session.getAttribute(Constant.CURRENT_USER_BINDINFO_FROM_EVENT_VIEW);
			if(null!=fan && null!=bind){
				return true;
			}*/
			if(null==fan){
				SysWxuser wxinfo = WechatEnv.wxuser;
				String appid = wxinfo.getAppid();
				String appSecret = wxinfo.getAppsecretd();
				
				String state = request.getParameter("state");
				String code = request.getParameter("code");
				if(!StringUtils.isEmpty(state) && !StringUtils.isEmpty(code)){
					WechatOperations options = new WechatOperations();
					JSONObject json = options.getWebAccessToken(code,appid,appSecret);
					Integer errcode = json.getInteger("errcode");
					if(null != errcode && errcode.intValue() != 0){
						logger.error("获取网页AccessToken异常：" + json.getString("errmsg"));
						return false;
					}
					String openId = json.getString("openid");
					if(!StringUtils.isEmpty(openId)){
						WxFansUserExample example = new WxFansUserExample();
						example.createCriteria().andOpenidEqualTo(openId);
						PageHelper.startPage(1,1);
						List<WxFansUser> userList = wxFansUserService.selectByExample(example);
						WxFansUser wxfansUser=null;
						if(userList != null && userList.size() > 0){
							wxfansUser = userList.get(0);
						} else{
							wxfansUser = this.wxFansUserService.selectByOpenId(openId);
							if(null==wxfansUser){
								String token = sysWxTokenService.getAccessToken(wxinfo);
								String requestUrl = WxApi.getFansInfoUrl(token, openId);
								String responseStr = HttpUtils.httpsGet(requestUrl);
								JSONObject jSONObject = JSON.parseObject(responseStr);
								Fans fans = (Fans)JSON.parseObject(jSONObject.toString(), Fans.class);
								wxfansUser = new WxFansUser();
								wxfansUser.setSubscribe(fans.getSubscribe().intValue());
								BeanUtils.copyProperties(fans, wxfansUser);
								//wxfansUser.setTags(StringUtils.join(fans.getTagid_list()));
								wxfansUser.setNickname(SpecialCharacterFilterUtil.utf8ToUnicode(fans.getNickname()));
								wxfansUser.setWxid(wxinfo.getWxid());
								if(fans.getSubscribe().intValue()==1){
									wxfansUser.setSubscribeTime(new Date());
								}
								this.wxFansUserService.insert(wxfansUser);
							}
						}
						session.setAttribute(Constant.CURRENT_USER_FANINFO_FROM_EVENT_VIEW, wxfansUser);
						
						/*ExamBindingsExample bindExample = new ExamBindingsExample();
						bindExample.createCriteria().andUserIdEqualTo(wxfansUser.getId());
						PageHelper.startPage(1,1);
						List<ExamBindings> bindList = this.examBindingsService.list(bindExample);
						if(bindList.size()==0){
							String serverPath = getAbsolutelyServerPath(request);
							session.setAttribute(Constant.BINDED_BACKURL_KEY, serverPath.concat("/").concat(servletPath));
							response.sendRedirect(getAbsolutelyServerPath(request).concat("/anon/mine/bind"));
							return false;
						}
						bind = bindList.get(0);
						session.setAttribute(Constant.CURRENT_USER_BINDINFO_FROM_EVENT_VIEW, bind);*/
						return true;
					}else{
						response.sendRedirect(getAbsolutelyServerPath(request).concat("/").concat(servletPath));
						return false;
					}
				} else{
					if(null==state){
						state="0";
					}
					String authorizeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
							.concat(appid).concat("&redirect_uri=")
							.concat(getAbsolutelyServerPath(request).concat(servletPath))
							.concat("&response_type=code&scope=snsapi_base&state="+state)
							.concat("#wechat_redirect");
					response.sendRedirect(authorizeUrl);
					return false;
				}
			}
			/*if(null==bind){
				ExamBindingsExample bindExample = new ExamBindingsExample();
				bindExample.createCriteria().andUserIdEqualTo(fan.getId());
				PageHelper.startPage(1,1);
				List<ExamBindings> bindList = this.examBindingsService.list(bindExample);
				if(bindList.size()==0){
					String serverPath = getAbsolutelyServerPath(request);
					session.setAttribute(Constant.BINDED_BACKURL_KEY, serverPath.concat("/").concat(servletPath));
					response.sendRedirect(getAbsolutelyServerPath(request).concat("/anon/mine/bind"));
					return false;
				}
				bind = this.examBindingsService.findOneById(fan.getId());
				session.setAttribute(Constant.CURRENT_USER_BINDINFO_FROM_EVENT_VIEW, bind);
				return true;
			}*/
		}
		return true;
	}

	private boolean isNeedHandle(String servletPath, Object handler){
		if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
			HandlerMethod handlerMethod = ((HandlerMethod) handler);
			OAuth2AndBind oauth = handlerMethod.getMethodAnnotation(OAuth2AndBind.class);
			if (oauth == null)
				return false;
			return true;
		}
		return (handleUrlList != null && handleUrlList.contains(servletPath))
			|| servletPath.startsWith(this.handlePrefix);
	}

	@Override
	public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,
		ModelAndView modelAndView) throws Exception{
	}

	@Override
	public void afterCompletion(HttpServletRequest request,HttpServletResponse response,
		Object handler,Exception ex) throws Exception{

	}

	public void setHandleUrlList(List<String> handleUrlList){

		this.handleUrlList = handleUrlList;
	}

	public void setHandlePrefix(String handlePrefix){

		this.handlePrefix = handlePrefix;
	}

	private final String getAbsolutelyServerPath(HttpServletRequest request){
		String refererUrl = request.getScheme().concat("://").concat(request.getServerName()); 
		int port = request.getServerPort();
        if(port>0 && port!=80){
        	refererUrl = refererUrl.concat(":").concat(port+"");
        }
        refererUrl=refererUrl.concat(request.getContextPath());
        return refererUrl;
	}
}